package kr.saeildamil.androidforstudy2.ch33;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;

import kr.saeildamil.androidforstudy2.R;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class PlayAudio extends Activity {
	ArrayList<String> mList;
	int mIdx;
	MediaPlayer mPlayer;
	Button mPlayBtn;
	TextView mFileName;
	SeekBar mProgress;
	boolean wasPlaying;
	String mSdPath;
	
	MediaRecorder mRecorder;
	Button mRecordStart;
	Button mRecordPlay;
	boolean mIsRecording;
	String mRecordPath;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ch33_playaudio);
		
		mList = new ArrayList<String>();
		mPlayer = new MediaPlayer();
	
		String external = Environment.getExternalStorageState();
		if(!external.equalsIgnoreCase(Environment.MEDIA_MOUNTED)){
			Toast.makeText(this, "Can't find SDCard!", Toast.LENGTH_SHORT).show();
			finish();
			return;
		}
		
		mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/CyphersBGM";
	 // mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath(); ..이건 Emulator 용;
		File sdRoot = new File(mSdPath);
		
		FilenameFilter filter = new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String filename) {
				return filename.endsWith("mp3");
			}
		};
		
		String[] mpList = sdRoot.list(filter);
		if(mpList.length == 0){
			Toast.makeText(this, "There's no file!", Toast.LENGTH_SHORT).show();
			finish();
			return;
		}
		
		for(String str : mpList){
			// Toast.makeText(this, str, 0).show();
			mList.add(mSdPath + "/" + str);
		}
		
		mFileName = (TextView) findViewById(R.id.filename);
		mPlayBtn = (Button) findViewById(R.id.play);
		mProgress = (SeekBar) findViewById(R.id.progress);
		
		mPlayer.setOnCompletionListener(mOnComplete);
		mPlayer.setOnSeekCompleteListener(mOnSeekComplete);
		mPlayer.setOnErrorListener(mOnError);
		
		mProgress.setOnSeekBarChangeListener(mOnSeekChange);
		mProgressHandler.sendEmptyMessageDelayed(0, 200);
		
		if(! loadMedia(mIdx)){
			Toast.makeText(this, "Can't read files", Toast.LENGTH_SHORT).show();
			finish();
		}
		
		mRecordStart = (Button) findViewById(R.id.record_start);
		mRecordPlay = (Button) findViewById(R.id.record_play);
		
		mRecordStart.setOnClickListener(mOnRecordStart);
		mRecordPlay.setOnClickListener(mOnRecordPlay);
	}
	
	OnClickListener mOnRecordStart = new Button.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			if(! mIsRecording){
				String path = Environment.getExternalStorageDirectory().getAbsolutePath();
				mRecordPath = path + "/recaudio.3gp";
				if(mRecorder==null){
					mRecorder = new MediaRecorder();
				}else{
					mRecorder.reset();
				}
				mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
				mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
				mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
				mRecorder.setOutputFile(mRecordPath);
				try {
					mRecorder.prepare();
				} catch (IllegalStateException e) {
					Toast.makeText(PlayAudio.this, "IllegalStateException!", Toast.LENGTH_SHORT).show();
				} catch (IOException e) {
					Toast.makeText(PlayAudio.this, "IOException!", Toast.LENGTH_SHORT).show();
				}
				mRecorder.start();
				mIsRecording = true;
				mRecordStart.setText("Stop");
			}else{
				mRecorder.stop();
				mRecorder.release();
				mRecorder = null;
				mIsRecording = false;
				mRecordStart.setText("Start");
			}
		}
	};
	
	OnClickListener mOnRecordPlay = new Button.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			if(mRecordPath.length()==0 || mIsRecording){
				Toast.makeText(PlayAudio.this, "You must record first!", Toast.LENGTH_SHORT).show();
			}
			MediaPlayer player = new MediaPlayer();
			try {
				player.setDataSource(mRecordPath);
			} catch (IllegalArgumentException e) {
				Toast.makeText(PlayAudio.this, "IllegalArgumentException!", Toast.LENGTH_SHORT).show();
			} catch (SecurityException e) {
				Toast.makeText(PlayAudio.this, "SecurityException!", Toast.LENGTH_SHORT).show();
			} catch (IllegalStateException e) {
				Toast.makeText(PlayAudio.this, "IllegalStateException!", Toast.LENGTH_SHORT).show();
			} catch (IOException e) {
				Toast.makeText(PlayAudio.this, "IOException!", Toast.LENGTH_SHORT).show();
			}
		}
	};
	
	 boolean loadMedia(int mIdx) {
		try {
			mPlayer.setDataSource(mList.get(mIdx));
			mPlayer.prepare();
		} catch (IllegalArgumentException e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
		} catch (SecurityException e) {
		    Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
		} catch (IllegalStateException e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
		}
		
		mFileName.setText("File : " + mList.get(mIdx));
		mProgress.setMax(mPlayer.getDuration());
		return true;
	}
	
	protected void onPause() {
		super.onPause();
		if(mPlayer != null){
			mPlayer.release();
			mPlayer=null;
		}
		if(mRecorder != null){
			mRecorder.release();
			mRecorder = null;
		}
	};
	
	Handler mProgressHandler = new Handler(){
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(mPlayer == null) return;
			if(mPlayer.isPlaying()){
			mProgress.setProgress(mPlayer.getCurrentPosition());
		};
		mProgressHandler.sendEmptyMessageDelayed(0, 200);
	}
};
		
	
	OnSeekBarChangeListener mOnSeekChange = new OnSeekBarChangeListener() {
		
		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
		
		}
		
		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
			wasPlaying = mPlayer.isPlaying();
			if(wasPlaying){
				mPlayer.pause();
			}
		}
		
		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			if(fromUser){
				mPlayer.seekTo(progress);	// 사용자가 선택한 곳으로 이동;
			}
		}
	};
	
	OnSeekCompleteListener mOnSeekComplete = new OnSeekCompleteListener() {
		
		@Override
		public void onSeekComplete(MediaPlayer mp) {
			if(wasPlaying){
				mPlayer.start();
			}
		}
	};
	
	OnCompletionListener mOnComplete = new OnCompletionListener() {
		
		@Override
		public void onCompletion(MediaPlayer mp) {
			// 모든 곡 재생 완료 시, 그렇다면 처음으로.. 아니면 다음으로;
			mIdx = (mIdx == mList.size()-1? 0:mIdx+1);
			mPlayer.reset();	// 곡이 바뀌므로 reset() 필요;
			loadMedia(mIdx);
			mPlayer.start();
		}
	};
	
	OnErrorListener mOnError = new OnErrorListener() {
		
		@Override
		public boolean onError(MediaPlayer mp, int what, int extra) {
			String error = "Error occured. what : " + what + " , extra : " + extra;
			Toast.makeText(PlayAudio.this, error, Toast.LENGTH_LONG).show();
			return false;
		}
	};
	
	public void mOnClick(View v){
		switch (v.getId()) {
		case R.id.play:
			if(! mPlayer.isPlaying()){
			mPlayer.start();
			mPlayBtn.setText("Pause");
			}else{
				mPlayer.pause();
				mPlayBtn.setText("Play");
			}
			break;
		case R.id.stop:
			mPlayer.stop();
			mPlayBtn.setText("Play");
			mProgress.setProgress(0);
			try {
				mPlayer.prepare();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		case R.id.prev:
			break;
		case R.id.next:
			boolean wasPlaying = mPlayer.isPlaying();
			if(v.getId() == R.id.prev){
				mIdx = (mIdx == 0? mList.size()-1:mIdx-1);
			}else{
				mIdx = (mIdx == mList.size()-1? 0:mIdx+1);
			}
			
			mPlayer.reset();
			loadMedia(mIdx);
			
			if(wasPlaying){
				mPlayer.start();
				mPlayBtn.setText("Pause");
			}
			break;
		}
	}
}
